﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System;
using System.Drawing;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Dnn;
using OpenCvSharp.Extensions; // 用于 Mat -> Bitmap 转换


namespace LockScreen1
{
    public partial class YanZheng : Form
    {
        private VideoCapture cap;
        private Net net;
        private System.Windows.Forms.Timer timer;

        public YanZheng()
        {
            InitializeComponent();

            // 加载 MobileNetSSD 模型
            string prototxt = "MobileNetSSD_deploy.prototxt";
            string model = "MobileNetSSD_deploy.caffemodel";
            net = CvDnn.ReadNetFromCaffe(prototxt, model);

            // 打开摄像头
            cap = new VideoCapture(0);
            if (!cap.IsOpened())
            {
                MessageBox.Show("无法打开摄像头");
                return;
            }

            // 定时器刷新视频
            timer = new System.Windows.Forms.Timer();
            timer.Interval = 50; // 20 FPS
            timer.Tick += ProcessFrame;
            timer.Start();
        }

        // MobileNetSSD 类别标签
        private readonly string[] classes = {
            "background", "aeroplane", "bicycle", "bird", "boat",
            "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
            "dog", "horse", "motorbike", "person", "pottedplant",
            "sheep", "sofa", "train", "tvmonitor"
        };

        private const int personClassId = 15;

        private void ProcessFrame(object sender, EventArgs e)
        {
            Mat frame = new Mat();
            cap.Read(frame);
            if (frame.Empty()) return;

            int w = frame.Width;
            int h = frame.Height;

            // 预处理
            var blob = CvDnn.BlobFromImage(frame, 0.007843, new OpenCvSharp.Size(300, 300),
                                           new Scalar(127.5, 127.5, 127.5), false, false);
            net.SetInput(blob);
            var detections = net.Forward();

            float largestArea = 0;
            OpenCvSharp.Rect largestBox = new OpenCvSharp.Rect();

            // 遍历检测结果
            for (int i = 0; i < detections.Size(2); i++)
            {
                float confidence = detections.At<float>(0, 0, i, 2);
                int classId = (int)detections.At<float>(0, 0, i, 1);

                if (confidence > 0.5 && classId == personClassId)
                {
                    int x1 = (int)(detections.At<float>(0, 0, i, 3) * w);
                    int y1 = (int)(detections.At<float>(0, 0, i, 4) * h);
                    int x2 = (int)(detections.At<float>(0, 0, i, 5) * w);
                    int y2 = (int)(detections.At<float>(0, 0, i, 6) * h);

                    var rect = new OpenCvSharp.Rect(x1, y1, x2 - x1, y2 - y1);
                    float area = rect.Width * rect.Height;

                    if (area > largestArea)
                    {
                        largestArea = area;
                        largestBox = rect;
                    }
                }
            }

            // 绘制红框和占比
            if (largestArea > 0)
            {
                double ratio = largestArea / (double)(w * h);
                Cv2.Rectangle(frame, largestBox, new Scalar(0, 0, 255), 2);
                Cv2.PutText(frame, $"Person ratio: {ratio:P2}",
                            new OpenCvSharp.Point(largestBox.X, largestBox.Y - 10),
                            HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 255), 2);
            }
            else
            {
                Cv2.PutText(frame, "No person detected",
                            new OpenCvSharp.Point(10, 30),
                            HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 255), 2);
            }

            // 显示到 PictureBox
            pictureBox1.Image?.Dispose();
            pictureBox1.Image = BitmapConverter.ToBitmap(frame);
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            timer?.Stop();
            cap?.Release();
            Cv2.DestroyAllWindows();
        }
    }
}
